package net.fpeg.kotlin.msa.wordbase.service

import net.fpeg.kotlin.msa.wordbase.dao.WordSourceDao
import net.fpeg.kotlin.msa.wordbase.entity.WordSource
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import javax.transaction.Transactional


@Service
class WordSourceService {
    @Autowired
    lateinit var wordSourceDao: WordSourceDao

    @Autowired
    lateinit var wordUserService: WordUserService

    @Autowired
    lateinit var wordSentenceService: WordSentenceService

    /**
     * 遍历树所有节点
     * @param sourceId 起始节点id
     */
    fun get(sourceId: Long) = wordSourceDao.getById(sourceId)

    fun getOne(sourceId: Long) = get(sourceId) ?: throw Exception("来源不存在")

    fun getTree(id: Long) = wordSourceDao.getOne(
            wordUserService.getOne(id).defaultSource?.id ?: throw Exception("根来源未定义")
    )

    fun add(id: Long, sourceId: Long?, value: String) =
            wordSourceDao.save(WordSource(value,
                    when (sourceId) {
                        null -> null
                        else -> getOne(sourceId)
                    }, wordUserService.getOne(id)))

    fun edit(id: Long, sourceId: Long, value: String) {
        getOne(sourceId).run {
            this.value = value
            wordSourceDao.save(this)
        }
    }

    @Transactional
    fun remove(uid: Long, sourceId: Long) {
        val defaultWordSource = wordUserService.getOne(uid).defaultSource ?: throw Exception("卧槽")
        wordSentenceService.find(uid, sourceId).map {
            it.apply {
                wordSource = defaultWordSource
            }
        }.let { wordSentenceService.save(it) }
        wordSourceDao.deleteById(sourceId)
    }

    fun findIds(sourceId: Long): Set<Long> {
        val x = mutableSetOf<Long>()
        r(get(sourceId), x)
        return x
    }

    fun r(currentSource: WordSource?, resultList: MutableSet<Long>) {
        if (currentSource?.id != null) {
            resultList.add(currentSource.id ?: throw Exception("这不合理"))
            for (source in currentSource.wordSourceChildren) {
                r(source, resultList)
            }
        }

    }
}